import logging.handlers
import os
import shutil
import stat
import sys
import tarfile
import time

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
fh = logging.handlers.RotatingFileHandler("info-build.log", mode='a', maxBytes=20 * 1024 * 1024, backupCount=10)
LOG_FORMAT = "[%(asctime)s]:%(levelname)s-[%(funcName)s]:%(message)s"
fh.setFormatter(logging.Formatter(LOG_FORMAT))
logger.addHandler(fh)
ch = logging.StreamHandler()
ch.setFormatter(logging.Formatter(LOG_FORMAT))
logger.addHandler(ch)


def get_val_from_env(env_key, is_check=True):
    value = os.getenv(env_key)
    if value is None or value == "":
        err_msg = "required env is not provided! key: %s  value: %s" % (env_key, value)
        if is_check is False:
            logger.info(err_msg)
            return ""
        else:
            logger.critical(err_msg)
            raise Exception(err_msg)
    return value


def cmd(shell):
    logger.debug(">>>>>>>>>>>>>>> exec start: %s", shell)
    ret = os.system(shell)
    logger.debug("<<<<<<<<<<<<<<< exec end: %s  %s", shell, ret)
    if ret != 0:
        msg = "command run error: %s" % shell
        logger.critical(msg)
        raise Exception(msg)


def cmd_with_result(shell, is_log=True):
    if is_log:
        logger.debug(">>>>>>>>>>>>>>> exec start: %s", shell)
    proc = os.popen(shell)
    result = proc.readlines()
    output = ''
    for line in result:
        output += line
        line = line.strip('\r\n')
        if is_log:
            logger.info(line)
    ret = proc.close()
    if is_log:
        logger.debug("<<<<<<<<<<<<<<< exec end: %s ret %s", shell, ret)
    return output, ret


def write_file(full_path, content):
    with open(full_path, 'w', encoding='utf-8') as f:
        f.write(content)


def make_dir_p(dir_path):
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)
        logger.debug("make dir (%s) path, dir not exists." % dir_path)
    else:
        logger.debug("make dir (%s) path, dir exists.", dir_path)


def join_path(*args):
    return os.path.join(*args)


def url_retrieve(url, dst_path):
    logger.info("download url %s to %s ", url, dst_path)
    if sys.version_info[0] <= 2:
        import urllib
        return urllib.urlretrieve(url, dst_path)
    elif sys.version_info[0] <= 3:
        import urllib.request
        return urllib.request.urlretrieve(url, dst_path)


def create_tar_gz(source_dir, output_file):
    with tarfile.open(output_file, "w:gz") as tar:
        for root, dirs, files in os.walk(source_dir):
            for file in files:
                file_path = join_path(root, file)
                set_777_perm(file_path)
                tar.add(file_path, arcname=file_path)


def remove_file_or_dir(path):
    if not os.path.exists(path):
        logger.debug("file or path %s is not exists,need not to remove", path)
        return
    logger.debug("file or path %s is exists", path)
    if os.path.isfile(path):
        os.remove(path)
        logger.debug("remove file %s", path)
    else:
        shutil.rmtree(path)
        logger.debug("remove path file %s", path)


def set_777_perm(path):
    cmd('chmod +x %s' % path)


def check_file_exists(file_path, error_msg=""):
    if not os.path.exists(file_path) or not os.path.isfile(file_path):
        msg = "%s! file (%s) not exists, can't be continue" % (error_msg, file_path)
        logger.critical(msg)
        raise Exception(msg)
    logger.debug("check file (%s) path, file exists.", file_path)


def check_dir_exists(dir_path, error_msg=""):
    if not os.path.exists(dir_path) or not os.path.isdir(dir_path):
        msg = "%s! dir (%s) not exists, can't be continue" % (error_msg, dir_path)
        logger.critical(msg)
        raise Exception(msg)
    logger.debug("check dir (%s) path, dir exists.", dir_path)


def copy_file(src_full_path, dst_full_path, is_overwrite=True):
    check_file_exists(src_full_path)
    logger.info("copy file from %s to %s ", src_full_path, dst_full_path)
    is_exist = False
    if os.path.exists(dst_full_path):
        logger.info("file %s exist", dst_full_path)
        is_exist = True
    if not is_exist or is_overwrite:
        shutil.copyfile(src_full_path, dst_full_path)
        check_file_exists(dst_full_path)


def release_package_remove_src(src_full_path, target_tar_gz_file):
    create_tar_gz(src_full_path, target_tar_gz_file)
    remove_file_or_dir(src_full_path)
